home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / rpc3.9 / part07 < prev    next >
Encoding:
Internet Message Format  |  1988-02-27  |  53.4 KB

  1. Subject:  v13i084:  Sun RPC, release 3.9, Part07/15
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Stephen X. Nahm <sxn@Sun.COM>
  7. Posting-number: Volume 13, Issue 84
  8. Archive-name: rpc3.9/part07
  9.  
  10. #! /bin/sh
  11. # This is a shell archive. To extract, remove the header and type "sh filename"
  12. #
  13. echo x - rpcgen
  14. echo creating directory rpcgen
  15. mkdir rpcgen
  16. cd rpcgen
  17. echo x - Makefile
  18. cat > Makefile <<'Funky_Stuff'
  19. #
  20. # @(#)Makefile    1.2 87/11/09 3.9 RPCSRC
  21. #
  22. # Makefile for rpc protocol compiler
  23. # Copyright (C) 1987, Sun Microsystems, Inc.
  24. #
  25. SRCS= rpc_main.c rpc_hout.c rpc_cout.c rpc_parse.c rpc_scan.c rpc_util.c \
  26.     rpc_svcout.c rpc_clntout.c
  27. HDRS= rpc_util.h rpc_parse.h rpc_scan.h
  28. OBJS= rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o rpc_scan.o rpc_util.o \
  29.     rpc_svcout.o rpc_clntout.o
  30.  
  31. GOAL=rpcgen
  32. CFLAGS = -O
  33. DESTDIR=
  34.  
  35. $(GOAL): $(OBJS)
  36.     $(CC) $(CFLAGS) $(OBJS) -o $@
  37.  
  38. install: $(GOAL)
  39.     @echo "Installing the RPC Protocol Compiler"
  40.     install -s $(GOAL) $(DESTDIR)/usr/bin
  41.  
  42. lint: $(SRCS) $(HDRS)
  43.     lint $(SRCS)
  44.  
  45. clean:
  46.     rm -f $(GOAL) $(OBJS)
  47.  
  48. depend: $(SRCS) $(HDRS)
  49.     @${CC} ${CFLAGS} -M ${SRCS} > makedep
  50.     @echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  51.     @echo '$$r makedep' >>eddep
  52.     @echo 'w' >>eddep
  53.     @cp Makefile makefile.bak
  54.     @ed - Makefile < eddep
  55.     @rm eddep makedep makefile.bak
  56.  
  57. depend.42BSD depend.42bsd:
  58.     cp /dev/null x.c
  59.     for i in $(SRCS) ; do \
  60.               (/bin/grep '^#[         ]*include' x.c $$i | sed \
  61.                       -e '/\.\.\/h/d' \
  62.                       -e '/\.\.\/ufs/d' \
  63.                       -e 's,<\(.*\)>,"/usr/include/\1",' \
  64.                       -e 's/:[^"]*"\([^"]*\)".*/: \1/' \
  65.                       -e 's/\.c/\.o/' >>makedep); done
  66.     echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
  67.     echo '$$r makedep' >>eddep
  68.     echo 'w' >>eddep
  69.     cp Makefile Makefile.bak
  70.     ed - Makefile < eddep
  71.     rm eddep makedep x.c
  72.     echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile
  73.     echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile
  74.     echo '# see make depend above' >> Makefile
  75.  
  76. # DO NOT DELETE THIS LINE
  77.  
  78.  
  79. Funky_Stuff
  80. len=`wc -c < Makefile`
  81. if [ $len !=     1618 ] ; then
  82.   echo error: Makefile was $len bytes long, should have been     1618
  83. fi
  84. echo x - rpc_clntout.c
  85. cat > rpc_clntout.c <<'Funky_Stuff'
  86. /* @(#)rpc_clntout.c    1.2 87/11/24 3.9 RPCSRC */
  87. /*
  88.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  89.  * unrestricted use provided that this legend is included on all tape
  90.  * media and as a part of the software program in whole or part.  Users
  91.  * may copy or modify Sun RPC without charge, but are not authorized
  92.  * to license or distribute it to anyone else except as part of a product or
  93.  * program developed by the user.
  94.  * 
  95.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  96.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  97.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  98.  * 
  99.  * Sun RPC is provided with no support and without any obligation on the
  100.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  101.  * modification or enhancement.
  102.  * 
  103.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  104.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  105.  * OR ANY PART THEREOF.
  106.  * 
  107.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  108.  * or profits or other special, indirect and consequential damages, even if
  109.  * Sun has been advised of the possibility of such damages.
  110.  * 
  111.  * Sun Microsystems, Inc.
  112.  * 2550 Garcia Avenue
  113.  * Mountain View, California  94043
  114.  */
  115. #ifndef lint
  116. static char sccsid[] = "@(#)rpc_clntout.c 1.2 87/06/24 (C) 1987 SMI";
  117. #endif
  118.  
  119. /*
  120.  * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
  121.  * Copyright (C) 1987, Sun Microsytsems, Inc.
  122.  */
  123. #include <stdio.h>
  124. #include <strings.h>
  125. #include "rpc_parse.h"
  126. #include "rpc_util.h"
  127.  
  128. #define DEFAULT_TIMEOUT 25    /* in seconds */
  129.  
  130. void
  131. write_stubs()
  132. {
  133.     list *l;
  134.     definition *def;
  135.  
  136.     f_print(fout, "\nstatic struct timeval TIMEOUT = { %d, 0 };\n",
  137.         DEFAULT_TIMEOUT);
  138.     for (l = defined; l != NULL; l = l->next) {
  139.         def = (definition *) l->val;
  140.         if (def->def_kind == DEF_PROGRAM) {
  141.             write_program(def);
  142.         }
  143.     }
  144. }
  145.  
  146.  
  147. static
  148. write_program(def)
  149.     definition *def;
  150. {
  151.     version_list *vp;
  152.     proc_list *proc;
  153.  
  154.     for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
  155.         for (proc = vp->procs; proc != NULL; proc = proc->next) {
  156.             f_print(fout, "\n");
  157.             ptype(proc->res_prefix, proc->res_type, 1);
  158.             f_print(fout, "*\n");
  159.             pvname(proc->proc_name, vp->vers_num);
  160.             f_print(fout, "(argp, clnt)\n");
  161.             f_print(fout, "\t");
  162.             ptype(proc->arg_prefix, proc->arg_type, 1);
  163.             f_print(fout, "*argp;\n");
  164.             f_print(fout, "\tCLIENT *clnt;\n");
  165.             f_print(fout, "{\n");
  166.             printbody(proc);
  167.             f_print(fout, "}\n\n");
  168.         }
  169.     }
  170. }
  171.  
  172. static char *
  173. ampr(type)
  174.     char *type;
  175. {
  176.     if (isvectordef(type, REL_ALIAS)) {
  177.         return ("");
  178.     } else {
  179.         return ("&");
  180.     }
  181. }
  182.  
  183. static
  184. printbody(proc)
  185.     proc_list *proc;
  186. {
  187.     f_print(fout, "\tstatic ");
  188.     if (streq(proc->res_type, "void")) {
  189.         f_print(fout, "char ");
  190.     } else {
  191.         ptype(proc->res_prefix, proc->res_type, 0);
  192.     }
  193.     f_print(fout, "res;\n");
  194.     f_print(fout, "\n");
  195.     f_print(fout, "\tbzero(%sres, sizeof(res));\n", ampr(proc->res_type));
  196.     f_print(fout,
  197.         "\tif (clnt_call(clnt, %s, xdr_%s, argp, xdr_%s, %sres, TIMEOUT) != RPC_SUCCESS) {\n",
  198.         proc->proc_name, stringfix(proc->arg_type),
  199.         stringfix(proc->res_type), ampr(proc->res_type));
  200.     f_print(fout, "\t\treturn (NULL);\n");
  201.     f_print(fout, "\t}\n");
  202.     if (streq(proc->res_type, "void")) {
  203.         f_print(fout, "\treturn ((void *)%sres);\n",
  204.             ampr(proc->res_type));
  205.     } else {
  206.         f_print(fout, "\treturn (%sres);\n", ampr(proc->res_type));
  207.     }
  208. }
  209. Funky_Stuff
  210. len=`wc -c < rpc_clntout.c`
  211. if [ $len !=     3441 ] ; then
  212.   echo error: rpc_clntout.c was $len bytes long, should have been     3441
  213. fi
  214. echo x - rpc_cout.c
  215. cat > rpc_cout.c <<'Funky_Stuff'
  216. /* @(#)rpc_cout.c    1.1 87/11/04 3.9 RPCSRC */
  217. /*
  218.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  219.  * unrestricted use provided that this legend is included on all tape
  220.  * media and as a part of the software program in whole or part.  Users
  221.  * may copy or modify Sun RPC without charge, but are not authorized
  222.  * to license or distribute it to anyone else except as part of a product or
  223.  * program developed by the user.
  224.  * 
  225.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  226.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  227.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  228.  * 
  229.  * Sun RPC is provided with no support and without any obligation on the
  230.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  231.  * modification or enhancement.
  232.  * 
  233.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  234.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  235.  * OR ANY PART THEREOF.
  236.  * 
  237.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  238.  * or profits or other special, indirect and consequential damages, even if
  239.  * Sun has been advised of the possibility of such damages.
  240.  * 
  241.  * Sun Microsystems, Inc.
  242.  * 2550 Garcia Avenue
  243.  * Mountain View, California  94043
  244.  */
  245. #ifndef lint
  246. static char sccsid[] = "@(#)rpc_cout.c 1.8 87/06/24 (C) 1987 SMI";
  247. #endif
  248.  
  249. /*
  250.  * rpc_cout.c, XDR routine outputter for the RPC protocol compiler 
  251.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  252.  */
  253. #include <stdio.h>
  254. #include <strings.h>
  255. #include "rpc_util.h"
  256. #include "rpc_parse.h"
  257.  
  258. /*
  259.  * Emit the C-routine for the given definition 
  260.  */
  261. void
  262. emit(def)
  263.     definition *def;
  264. {
  265.     if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
  266.         return;
  267.     }
  268.     print_header(def);
  269.     switch (def->def_kind) {
  270.     case DEF_UNION:
  271.         emit_union(def);
  272.         break;
  273.     case DEF_ENUM:
  274.         emit_enum(def);
  275.         break;
  276.     case DEF_STRUCT:
  277.         emit_struct(def);
  278.         break;
  279.     case DEF_TYPEDEF:
  280.         emit_typedef(def);
  281.         break;
  282.     }
  283.     print_trailer();
  284. }
  285.  
  286. static
  287. findtype(def, type)
  288.     definition *def;
  289.     char *type;
  290. {
  291.     if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
  292.         return (0);
  293.     } else {
  294.         return (streq(def->def_name, type));
  295.     }
  296. }
  297.  
  298. static
  299. undefined(type)
  300.     char *type;
  301. {
  302.     definition *def;
  303.  
  304.     def = (definition *) FINDVAL(defined, type, findtype);
  305.     return (def == NULL);
  306. }
  307.  
  308.  
  309. static
  310. print_header(def)
  311.     definition *def;
  312. {
  313.     space();
  314.     f_print(fout, "bool_t\n");
  315.     f_print(fout, "xdr_%s(xdrs, objp)\n", def->def_name);
  316.     f_print(fout, "\tXDR *xdrs;\n");
  317.     f_print(fout, "\t%s ", def->def_name);
  318.     if (def->def_kind != DEF_TYPEDEF ||
  319.         !isvectordef(def->def.ty.old_type, def->def.ty.rel)) {
  320.         f_print(fout, "*");
  321.     }
  322.     f_print(fout, "objp;\n");
  323.     f_print(fout, "{\n");
  324. }
  325.  
  326. static
  327. print_trailer()
  328. {
  329.     f_print(fout, "\treturn (TRUE);\n");
  330.     f_print(fout, "}\n");
  331.     space();
  332. }
  333.  
  334.  
  335. static
  336. print_ifopen(indent, name)
  337.     int indent;
  338.     char *name;
  339. {
  340.     tabify(fout, indent);
  341.     f_print(fout, "if (!xdr_%s(xdrs", name);
  342. }
  343.  
  344.  
  345. static
  346. print_ifarg(arg)
  347.     char *arg;
  348. {
  349.     f_print(fout, ", %s", arg);
  350. }
  351.  
  352.  
  353. static
  354. print_ifsizeof(prefix, type)
  355.     char *prefix;
  356.     char *type;
  357. {
  358.     if (streq(type, "bool")) {
  359.         f_print(fout, ", sizeof(bool_t), xdr_bool");
  360.     } else {
  361.         f_print(fout, ", sizeof(");
  362.         if (undefined(type) && prefix) {
  363.             f_print(fout, "%s ", prefix);
  364.         }
  365.         f_print(fout, "%s), xdr_%s", type, type);
  366.     }
  367. }
  368.  
  369. static
  370. print_ifclose(indent)
  371.     int indent;
  372. {
  373.     f_print(fout, ")) {\n");
  374.     tabify(fout, indent);
  375.     f_print(fout, "\treturn (FALSE);\n");
  376.     tabify(fout, indent);
  377.     f_print(fout, "}\n");
  378. }
  379.  
  380. static
  381. space()
  382. {
  383.     f_print(fout, "\n\n");
  384. }
  385.  
  386. static
  387. print_ifstat(indent, prefix, type, rel, amax, objname, name)
  388.     int indent;
  389.     char *prefix;
  390.     char *type;
  391.     relation rel;
  392.     char *amax;
  393.     char *objname;
  394.     char *name;
  395. {
  396.     char *alt = NULL;
  397.  
  398.     switch (rel) {
  399.     case REL_POINTER:
  400.         print_ifopen(indent, "pointer");
  401.         print_ifarg("(char **)");
  402.         f_print(fout, "%s", objname);
  403.         print_ifsizeof(prefix, type);
  404.         break;
  405.     case REL_VECTOR:
  406.         if (streq(type, "string")) {
  407.             alt = "string";
  408.         } else if (streq(type, "opaque")) {
  409.             alt = "opaque";
  410.         }
  411.         if (alt) {
  412.             print_ifopen(indent, alt);
  413.             print_ifarg(objname);
  414.         } else {
  415.             print_ifopen(indent, "vector");
  416.             print_ifarg("(char *)");
  417.             f_print(fout, "%s", objname);
  418.         }
  419.         print_ifarg(amax);
  420.         if (!alt) {
  421.             print_ifsizeof(prefix, type);
  422.         }
  423.         break;
  424.     case REL_ARRAY:
  425.         if (streq(type, "string")) {
  426.             alt = "string";
  427.         } else if (streq(type, "opaque")) {
  428.             alt = "bytes";
  429.         }
  430.         if (streq(type, "string")) {
  431.             print_ifopen(indent, alt);
  432.             print_ifarg(objname);
  433.         } else {
  434.             if (alt) {
  435.                 print_ifopen(indent, alt);
  436.             } else {
  437.                 print_ifopen(indent, "array");
  438.             }
  439.             print_ifarg("(char **)");
  440.             if (*objname == '&') {
  441.                 f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
  442.                     objname, name, objname, name);
  443.             } else {
  444.                 f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
  445.                     objname, name, objname, name);
  446.             }
  447.         }
  448.         print_ifarg(amax);
  449.         if (!alt) {
  450.             print_ifsizeof(prefix, type);
  451.         }
  452.         break;
  453.     case REL_ALIAS:
  454.         print_ifopen(indent, type);
  455.         print_ifarg(objname);
  456.         break;
  457.     }
  458.     print_ifclose(indent);
  459. }
  460.  
  461.  
  462. /* ARGSUSED */
  463. static
  464. emit_enum(def)
  465.     definition *def;
  466. {
  467.     print_ifopen(1, "enum");
  468.     print_ifarg("(enum_t *)objp");
  469.     print_ifclose(1);
  470. }
  471.  
  472.  
  473. static
  474. emit_union(def)
  475.     definition *def;
  476. {
  477.     declaration *dflt;
  478.     case_list *cl;
  479.     declaration *cs;
  480.     char *object;
  481.     char *format = "&objp->%s_u.%s";
  482.  
  483.     print_stat(&def->def.un.enum_decl);
  484.     f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
  485.     for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
  486.         cs = &cl->case_decl;
  487.         f_print(fout, "\tcase %s:\n", cl->case_name);
  488.         if (!streq(cs->type, "void")) {
  489.             object = alloc(strlen(def->def_name) + strlen(format) +
  490.                        strlen(cs->name) + 1);
  491.             s_print(object, format, def->def_name, cs->name);
  492.             print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
  493.                      object, cs->name);
  494.             free(object);
  495.         }
  496.         f_print(fout, "\t\tbreak;\n");
  497.     }
  498.     dflt = def->def.un.default_decl;
  499.     if (dflt != NULL) {
  500.         if (!streq(dflt->type, "void")) {
  501.             f_print(fout, "\tdefault:\n");
  502.             object = alloc(strlen(def->def_name) + strlen(format) +
  503.                        strlen(dflt->name) + 1);
  504.             s_print(object, format, def->def_name, dflt->name);
  505.             print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
  506.                      dflt->array_max, object, dflt->name);
  507.             free(object);
  508.             f_print(fout, "\t\tbreak;\n");
  509.         }
  510.     } else {
  511.         f_print(fout, "\tdefault:\n");
  512.         f_print(fout, "\t\treturn (FALSE);\n");
  513.     }
  514.     f_print(fout, "\t}\n");
  515. }
  516.  
  517.  
  518.  
  519. static
  520. emit_struct(def)
  521.     definition *def;
  522. {
  523.     decl_list *dl;
  524.  
  525.     for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
  526.         print_stat(&dl->decl);
  527.     }
  528. }
  529.  
  530.  
  531.  
  532.  
  533. static
  534. emit_typedef(def)
  535.     definition *def;
  536. {
  537.     char *prefix = def->def.ty.old_prefix;
  538.     char *type = def->def.ty.old_type;
  539.     char *amax = def->def.ty.array_max;
  540.     relation rel = def->def.ty.rel;
  541.  
  542.     print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
  543. }
  544.  
  545.  
  546.  
  547.  
  548.  
  549. static
  550. print_stat(dec)
  551.     declaration *dec;
  552. {
  553.     char *prefix = dec->prefix;
  554.     char *type = dec->type;
  555.     char *amax = dec->array_max;
  556.     relation rel = dec->rel;
  557.     char name[256];
  558.  
  559.     if (isvectordef(type, rel)) {
  560.         s_print(name, "objp->%s", dec->name);
  561.     } else {
  562.         s_print(name, "&objp->%s", dec->name);
  563.     }
  564.     print_ifstat(1, prefix, type, rel, amax, name, dec->name);
  565. }
  566. Funky_Stuff
  567. len=`wc -c < rpc_cout.c`
  568. if [ $len !=     7284 ] ; then
  569.   echo error: rpc_cout.c was $len bytes long, should have been     7284
  570. fi
  571. echo x - rpc_hout.c
  572. cat > rpc_hout.c <<'Funky_Stuff'
  573. /* @(#)rpc_hout.c    1.2 87/11/30 3.9 RPCSRC */
  574. /*
  575.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  576.  * unrestricted use provided that this legend is included on all tape
  577.  * media and as a part of the software program in whole or part.  Users
  578.  * may copy or modify Sun RPC without charge, but are not authorized
  579.  * to license or distribute it to anyone else except as part of a product or
  580.  * program developed by the user.
  581.  * 
  582.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  583.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  584.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  585.  * 
  586.  * Sun RPC is provided with no support and without any obligation on the
  587.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  588.  * modification or enhancement.
  589.  * 
  590.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  591.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  592.  * OR ANY PART THEREOF.
  593.  * 
  594.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  595.  * or profits or other special, indirect and consequential damages, even if
  596.  * Sun has been advised of the possibility of such damages.
  597.  * 
  598.  * Sun Microsystems, Inc.
  599.  * 2550 Garcia Avenue
  600.  * Mountain View, California  94043
  601.  */
  602. #ifndef lint
  603. static char sccsid[] = "@(#)rpc_hout.c 1.6 87/07/28 (C) 1987 SMI";
  604. #endif
  605.  
  606. /*
  607.  * rpc_hout.c, Header file outputter for the RPC protocol compiler 
  608.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  609.  */
  610. #include <stdio.h>
  611. #include <ctype.h>
  612. #include "rpc_util.h"
  613. #include "rpc_parse.h"
  614.  
  615.  
  616. /*
  617.  * Print the C-version of an xdr definition 
  618.  */
  619. void
  620. print_datadef(def)
  621.     definition *def;
  622. {
  623.     if (def->def_kind != DEF_CONST) {
  624.         f_print(fout, "\n");
  625.     }
  626.     switch (def->def_kind) {
  627.     case DEF_STRUCT:
  628.         pstructdef(def);
  629.         break;
  630.     case DEF_UNION:
  631.         puniondef(def);
  632.         break;
  633.     case DEF_ENUM:
  634.         penumdef(def);
  635.         break;
  636.     case DEF_TYPEDEF:
  637.         ptypedef(def);
  638.         break;
  639.     case DEF_PROGRAM:
  640.         pprogramdef(def);
  641.         break;
  642.     case DEF_CONST:
  643.         pconstdef(def);
  644.         break;
  645.     }
  646.     if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
  647.         f_print(fout, "bool_t xdr_%s();\n", def->def_name);
  648.     }
  649.     if (def->def_kind != DEF_CONST) {
  650.         f_print(fout, "\n");
  651.     }
  652. }
  653.  
  654. static
  655. pconstdef(def)
  656.     definition *def;
  657. {
  658.     pdefine(def->def_name, def->def.co);
  659. }
  660.  
  661. static
  662. pstructdef(def)
  663.     definition *def;
  664. {
  665.     decl_list *l;
  666.     char *name = def->def_name;
  667.  
  668.     f_print(fout, "struct %s {\n", name);
  669.     for (l = def->def.st.decls; l != NULL; l = l->next) {
  670.         pdeclaration(name, &l->decl, 1);
  671.     }
  672.     f_print(fout, "};\n");
  673.     f_print(fout, "typedef struct %s %s;\n", name, name);
  674. }
  675.  
  676. static
  677. puniondef(def)
  678.     definition *def;
  679. {
  680.     case_list *l;
  681.     char *name = def->def_name;
  682.     declaration *decl;
  683.  
  684.     f_print(fout, "struct %s {\n", name);
  685.     decl = &def->def.un.enum_decl;
  686.     if (streq(decl->type, "bool")) {
  687.         f_print(fout, "\tbool_t %s;\n", decl->name);
  688.     } else {
  689.         f_print(fout, "\t%s %s;\n", decl->type, decl->name);
  690.     }
  691.     f_print(fout, "\tunion {\n");
  692.     for (l = def->def.un.cases; l != NULL; l = l->next) {
  693.         pdeclaration(name, &l->case_decl, 2);
  694.     }
  695.     decl = def->def.un.default_decl;
  696.     if (decl && !streq(decl->type, "void")) {
  697.         pdeclaration(name, decl, 2);
  698.     }
  699.     f_print(fout, "\t} %s_u;\n", name);
  700.     f_print(fout, "};\n");
  701.     f_print(fout, "typedef struct %s %s;\n", name, name);
  702. }
  703.  
  704.  
  705.  
  706. static
  707. pdefine(name, num)
  708.     char *name;
  709.     char *num;
  710. {
  711.     f_print(fout, "#define %s %s\n", name, num);
  712. }
  713.  
  714. static
  715. puldefine(name, num)
  716.     char *name;
  717.     char *num;
  718. {
  719.     f_print(fout, "#define %s ((u_long)%s)\n", name, num);
  720. }
  721.  
  722. static
  723. define_printed(stop, start)
  724.     proc_list *stop;
  725.     version_list *start;
  726. {
  727.     version_list *vers;
  728.     proc_list *proc;
  729.  
  730.     for (vers = start; vers != NULL; vers = vers->next) {
  731.         for (proc = vers->procs; proc != NULL; proc = proc->next) {
  732.             if (proc == stop) {
  733.                 return (0);
  734.             } else if (streq(proc->proc_name, stop->proc_name)) {
  735.                 return (1);
  736.             }
  737.         }
  738.     }
  739.     abort();
  740.     /* NOTREACHED */
  741. }
  742.  
  743.  
  744. static
  745. pprogramdef(def)
  746.     definition *def;
  747. {
  748.     version_list *vers;
  749.     proc_list *proc;
  750.  
  751.     puldefine(def->def_name, def->def.pr.prog_num);
  752.     for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
  753.         puldefine(vers->vers_name, vers->vers_num);
  754.         for (proc = vers->procs; proc != NULL; proc = proc->next) {
  755.             if (!define_printed(proc, def->def.pr.versions)) {
  756.                 puldefine(proc->proc_name, proc->proc_num);
  757.             }
  758.             pprocdef(proc, vers);
  759.         }
  760.     }
  761. }
  762.  
  763.  
  764. pprocdef(proc, vp)
  765.     proc_list *proc;
  766.     version_list *vp;
  767. {
  768.     f_print(fout, "extern ");
  769.     if (proc->res_prefix) {
  770.         if (streq(proc->res_prefix, "enum")) {
  771.             f_print(fout, "enum ");
  772.         } else {
  773.             f_print(fout, "struct ");
  774.         }
  775.     }
  776.     if (streq(proc->res_type, "bool")) {
  777.         f_print(fout, "bool_t *");
  778.     } else if (streq(proc->res_type, "string")) {
  779.         f_print(fout, "char **");
  780.     } else {
  781.         f_print(fout, "%s *", fixtype(proc->res_type));
  782.     }
  783.     pvname(proc->proc_name, vp->vers_num);
  784.     f_print(fout, "();\n");
  785. }
  786.  
  787. static
  788. penumdef(def)
  789.     definition *def;
  790. {
  791.     char *name = def->def_name;
  792.     enumval_list *l;
  793.     char *last = NULL;
  794.     int count = 0;
  795.  
  796.     f_print(fout, "enum %s {\n", name);
  797.     for (l = def->def.en.vals; l != NULL; l = l->next) {
  798.         f_print(fout, "\t%s", l->name);
  799.         if (l->assignment) {
  800.             f_print(fout, " = %s", l->assignment);
  801.             last = l->assignment;
  802.             count = 1;
  803.         } else {
  804.             if (last == NULL) {
  805.                 f_print(fout, " = %d", count++);
  806.             } else {
  807.                 f_print(fout, " = %s + %d", last, count++);
  808.             }
  809.         }
  810.         f_print(fout, ",\n");
  811.     }
  812.     f_print(fout, "};\n");
  813.     f_print(fout, "typedef enum %s %s;\n", name, name);
  814. }
  815.  
  816. static
  817. ptypedef(def)
  818.     definition *def;
  819. {
  820.     char *name = def->def_name;
  821.     char *old = def->def.ty.old_type;
  822.     char prefix[8];    /* enough to contain "struct ", including NUL */
  823.     relation rel = def->def.ty.rel;
  824.  
  825.  
  826.     if (!streq(name, old)) {
  827.         if (streq(old, "string")) {
  828.             old = "char";
  829.             rel = REL_POINTER;
  830.         } else if (streq(old, "opaque")) {
  831.             old = "char";
  832.         } else if (streq(old, "bool")) {
  833.             old = "bool_t";
  834.         }
  835.         if (undefined2(old, name) && def->def.ty.old_prefix) {
  836.             s_print(prefix, "%s ", def->def.ty.old_prefix);
  837.         } else {
  838.             prefix[0] = 0;
  839.         }
  840.         f_print(fout, "typedef ");
  841.         switch (rel) {
  842.         case REL_ARRAY:
  843.             f_print(fout, "struct {\n");
  844.             f_print(fout, "\tu_int %s_len;\n", name);
  845.             f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
  846.             f_print(fout, "} %s", name);
  847.             break;
  848.         case REL_POINTER:
  849.             f_print(fout, "%s%s *%s", prefix, old, name);
  850.             break;
  851.         case REL_VECTOR:
  852.             f_print(fout, "%s%s %s[%s]", prefix, old, name,
  853.                 def->def.ty.array_max);
  854.             break;
  855.         case REL_ALIAS:
  856.             f_print(fout, "%s%s *%s", prefix, old, name);
  857.             break;
  858.         }
  859.         f_print(fout, ";\n");
  860.     }
  861. }
  862.  
  863.  
  864. static
  865. pdeclaration(name, dec, tab)
  866.     char *name;
  867.     declaration *dec;
  868.     int tab;
  869. {
  870.     char buf[8];    /* enough to hold "struct ", include NUL */
  871.     char *prefix;
  872.     char *type;
  873.  
  874.     if (streq(dec->type, "void")) {
  875.         return;
  876.     }
  877.     tabify(fout, tab);
  878.     if (streq(dec->type, name) && !dec->prefix) {
  879.         f_print(fout, "struct ");
  880.     }
  881.     if (streq(dec->type, "string")) {
  882.         f_print(fout, "char *%s", dec->name);
  883.     } else {
  884.         prefix = "";
  885.         if (streq(dec->type, "bool")) {
  886.             type = "bool_t";
  887.         } else if (streq(dec->type, "opaque")) {
  888.             type = "char";
  889.         } else {
  890.             if (dec->prefix) {
  891.                 s_print(buf, "%s ", dec->prefix);
  892.                 prefix = buf;
  893.             }
  894.             type = dec->type;
  895.         }
  896.         switch (dec->rel) {
  897.         case REL_ALIAS:
  898.             f_print(fout, "%s%s %s", prefix, type, dec->name);
  899.             break;
  900.         case REL_VECTOR:
  901.             f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
  902.                 dec->array_max);
  903.             break;
  904.         case REL_POINTER:
  905.             f_print(fout, "%s%s *%s", prefix, type, dec->name);
  906.             break;
  907.         case REL_ARRAY:
  908.             f_print(fout, "struct {\n");
  909.             tabify(fout, tab);
  910.             f_print(fout, "\tu_int %s_len;\n", dec->name);
  911.             tabify(fout, tab);
  912.             f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
  913.             tabify(fout, tab);
  914.             f_print(fout, "} %s", dec->name);
  915.             break;
  916.         }
  917.     }
  918.     f_print(fout, ";\n");
  919. }
  920.  
  921.  
  922.  
  923. static
  924. undefined2(type, stop)
  925.     char *type;
  926.     char *stop;
  927. {
  928.     list *l;
  929.     definition *def;
  930.  
  931.     for (l = defined; l != NULL; l = l->next) {
  932.         def = (definition *) l->val;
  933.         if (def->def_kind != DEF_PROGRAM) {
  934.             if (streq(def->def_name, stop)) {
  935.                 return (1);
  936.             } else if (streq(def->def_name, type)) {
  937.                 return (0);
  938.             }
  939.         }
  940.     }
  941.     return (1);
  942. }
  943. Funky_Stuff
  944. len=`wc -c < rpc_hout.c`
  945. if [ $len !=     8172 ] ; then
  946.   echo error: rpc_hout.c was $len bytes long, should have been     8172
  947. fi
  948. echo x - rpc_main.c
  949. cat > rpc_main.c <<'Funky_Stuff'
  950. /* @(#)rpc_main.c    1.4 87/11/30 3.9 RPCSRC */
  951. /*
  952.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  953.  * unrestricted use provided that this legend is included on all tape
  954.  * media and as a part of the software program in whole or part.  Users
  955.  * may copy or modify Sun RPC without charge, but are not authorized
  956.  * to license or distribute it to anyone else except as part of a product or
  957.  * program developed by the user.
  958.  * 
  959.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  960.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  961.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  962.  * 
  963.  * Sun RPC is provided with no support and without any obligation on the
  964.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  965.  * modification or enhancement.
  966.  * 
  967.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  968.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  969.  * OR ANY PART THEREOF.
  970.  * 
  971.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  972.  * or profits or other special, indirect and consequential damages, even if
  973.  * Sun has been advised of the possibility of such damages.
  974.  * 
  975.  * Sun Microsystems, Inc.
  976.  * 2550 Garcia Avenue
  977.  * Mountain View, California  94043
  978.  */
  979. #ifndef lint
  980. static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI";
  981. #endif
  982.  
  983. /*
  984.  * rpc_main.c, Top level of the RPC protocol compiler. 
  985.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  986.  */
  987.  
  988. #include <stdio.h>
  989. #include <strings.h>
  990. #include <sys/file.h>
  991. #include "rpc_util.h"
  992. #include "rpc_parse.h"
  993. #include "rpc_scan.h"
  994.  
  995. #define EXTEND    1        /* alias for TRUE */
  996.  
  997. struct commandline {
  998.     int cflag;
  999.     int hflag;
  1000.     int lflag;
  1001.     int sflag;
  1002.     int mflag;
  1003.     char *infile;
  1004.     char *outfile;
  1005. };
  1006.  
  1007. static char *cmdname;
  1008. static char CPP[] = "/lib/cpp";
  1009. static char CPPFLAGS[] = "-C";
  1010. static char *allv[] = {
  1011.     "rpcgen", "-s", "udp", "-s", "tcp",
  1012. };
  1013. static int allc = sizeof(allv)/sizeof(allv[0]);
  1014.  
  1015. main(argc, argv)
  1016.     int argc;
  1017.     char *argv[];
  1018.  
  1019. {
  1020.     struct commandline cmd;
  1021.  
  1022.     if (!parseargs(argc, argv, &cmd)) {
  1023.         f_print(stderr,
  1024.             "usage: %s infile\n", cmdname);
  1025.         f_print(stderr,
  1026.             "       %s [-c | -h | -l | -m] [-o outfile] [infile]\n",
  1027.             cmdname);
  1028.         f_print(stderr,
  1029.             "       %s [-s udp|tcp]* [-o outfile] [infile]\n",
  1030.             cmdname);
  1031.         exit(1);
  1032.     }
  1033.     if (cmd.cflag) {
  1034.         c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile);
  1035.     } else if (cmd.hflag) {
  1036.         h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile);
  1037.     } else if (cmd.lflag) {
  1038.         l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile);
  1039.     } else if (cmd.sflag || cmd.mflag) {
  1040.         s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND,
  1041.              cmd.outfile, cmd.mflag);
  1042.     } else {
  1043.         c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
  1044.         reinitialize();
  1045.         h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
  1046.         reinitialize();
  1047.         l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
  1048.         reinitialize();
  1049.         s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
  1050.              "_svc.c", cmd.mflag);
  1051.     }
  1052.     exit(0);
  1053. }
  1054.  
  1055. /*
  1056.  * add extension to filename 
  1057.  */
  1058. static char *
  1059. extendfile(file, ext)
  1060.     char *file;
  1061.     char *ext;
  1062. {
  1063.     char *res;
  1064.     char *p;
  1065.  
  1066.     res = alloc(strlen(file) + strlen(ext) + 1);
  1067.     if (res == NULL) {
  1068.         abort();
  1069.     }
  1070.     p = rindex(file, '.');
  1071.     if (p == NULL) {
  1072.         p = file + strlen(file);
  1073.     }
  1074.     (void) strcpy(res, file);
  1075.     (void) strcpy(res + (p - file), ext);
  1076.     return (res);
  1077. }
  1078.  
  1079. /*
  1080.  * Open output file with given extension 
  1081.  */
  1082. static
  1083. open_output(infile, outfile)
  1084.     char *infile;
  1085.     char *outfile;
  1086. {
  1087.     if (outfile == NULL) {
  1088.         fout = stdout;
  1089.         return;
  1090.     }
  1091.     if (infile != NULL && streq(outfile, infile)) {
  1092.         f_print(stderr, "%s: output would overwrite %s\n", cmdname,
  1093.             infile);
  1094.         crash();
  1095.     }
  1096.     fout = fopen(outfile, "w");
  1097.     if (fout == NULL) {
  1098.         f_print(stderr, "%s: unable to open ", cmdname);
  1099.         perror(outfile);
  1100.         crash();
  1101.     }
  1102.     record_open(outfile);
  1103. }
  1104.  
  1105. /*
  1106.  * Open input file with given define for C-preprocessor 
  1107.  */
  1108. static
  1109. open_input(infile, define)
  1110.     char *infile;
  1111.     char *define;
  1112. {
  1113.     int pd[2];
  1114.  
  1115.     infilename = (infile == NULL) ? "<stdin>" : infile;
  1116.     (void) pipe(pd);
  1117.     switch (fork()) {
  1118.     case 0:
  1119.         (void) close(1);
  1120.         (void) dup2(pd[1], 1);
  1121.         (void) close(pd[0]);
  1122.         execl(CPP, CPP, CPPFLAGS, define, infile, NULL);
  1123.         perror("execl");
  1124.         exit(1);
  1125.     case -1:
  1126.         perror("fork");
  1127.         exit(1);
  1128.     }
  1129.     (void) close(pd[1]);
  1130.     fin = fdopen(pd[0], "r");
  1131.     if (fin == NULL) {
  1132.         f_print(stderr, "%s: ", cmdname);
  1133.         perror(infilename);
  1134.         crash();
  1135.     }
  1136. }
  1137.  
  1138. /*
  1139.  * Compile into an XDR routine output file
  1140.  */
  1141. static
  1142. c_output(infile, define, extend, outfile)
  1143.     char *infile;
  1144.     char *define;
  1145.     int extend;
  1146.     char *outfile;
  1147. {
  1148.     definition *def;
  1149.     char *include;
  1150.     char *outfilename;
  1151.     long tell;
  1152.  
  1153.     open_input(infile, define);    
  1154.     outfilename = extend ? extendfile(infile, outfile) : outfile;
  1155.     open_output(infile, outfilename);
  1156.     f_print(fout, "#include <rpc/rpc.h>\n");
  1157.     if (infile && (include = extendfile(infile, ".h"))) {
  1158.         f_print(fout, "#include \"%s\"\n", include);
  1159.         free(include);
  1160.     }
  1161.     tell = ftell(fout);
  1162.     while (def = get_definition()) {
  1163.         emit(def);
  1164.     }
  1165.     if (extend && tell == ftell(fout)) {
  1166.         (void) unlink(outfilename);
  1167.     }
  1168. }
  1169.  
  1170. /*
  1171.  * Compile into an XDR header file
  1172.  */
  1173. static
  1174. h_output(infile, define, extend, outfile)
  1175.     char *infile;
  1176.     char *define;
  1177.     int extend;
  1178.     char *outfile;
  1179. {
  1180.     definition *def;
  1181.     char *outfilename;
  1182.     long tell;
  1183.  
  1184.     open_input(infile, define);
  1185.     outfilename =  extend ? extendfile(infile, outfile) : outfile;
  1186.     open_output(infile, outfilename);
  1187.     tell = ftell(fout);
  1188.     while (def = get_definition()) {
  1189.         print_datadef(def);
  1190.     }
  1191.     if (extend && tell == ftell(fout)) {
  1192.         (void) unlink(outfilename);
  1193.     }
  1194. }
  1195.  
  1196. /*
  1197.  * Compile into an RPC service
  1198.  */
  1199. static
  1200. s_output(argc, argv, infile, define, extend, outfile, nomain)
  1201.     int argc;
  1202.     char *argv[];
  1203.     char *infile;
  1204.     char *define;
  1205.     int extend;
  1206.     char *outfile;
  1207.     int nomain;
  1208. {
  1209.     char *include;
  1210.     definition *def;
  1211.     int foundprogram;
  1212.     char *outfilename;
  1213.  
  1214.     open_input(infile, define);
  1215.     outfilename = extend ? extendfile(infile, outfile) : outfile;
  1216.     open_output(infile, outfilename);
  1217.     f_print(fout, "#include <stdio.h>\n");
  1218.     f_print(fout, "#include <rpc/rpc.h>\n");
  1219.     if (infile && (include = extendfile(infile, ".h"))) {
  1220.         f_print(fout, "#include \"%s\"\n", include);
  1221.         free(include);
  1222.     }
  1223.     foundprogram = 0;
  1224.     while (def = get_definition()) {
  1225.         foundprogram |= (def->def_kind == DEF_PROGRAM);
  1226.     }
  1227.     if (extend && !foundprogram) {
  1228.         (void) unlink(outfilename);
  1229.         return;
  1230.     }
  1231.     if (nomain) {
  1232.         write_programs((char *)NULL);
  1233.     } else {
  1234.         write_most();
  1235.         do_registers(argc, argv);
  1236.         write_rest();
  1237.         write_programs("static");
  1238.     }
  1239. }
  1240.  
  1241. static
  1242. l_output(infile, define, extend, outfile)
  1243.     char *infile;
  1244.     char *define;
  1245.     int extend;
  1246.     char *outfile;
  1247. {
  1248.     char *include;
  1249.     definition *def;
  1250.     int foundprogram;
  1251.     char *outfilename;
  1252.  
  1253.     open_input(infile, define);
  1254.     outfilename = extend ? extendfile(infile, outfile) : outfile;
  1255.     open_output(infile, outfilename);
  1256.     f_print(fout, "#include <rpc/rpc.h>\n");
  1257.     f_print(fout, "#include <sys/time.h>\n");
  1258.     if (infile && (include = extendfile(infile, ".h"))) {
  1259.         f_print(fout, "#include \"%s\"\n", include);
  1260.         free(include);
  1261.     }
  1262.     foundprogram = 0;
  1263.     while (def = get_definition()) {
  1264.         foundprogram |= (def->def_kind == DEF_PROGRAM);
  1265.     }
  1266.     if (extend && !foundprogram) {
  1267.         (void) unlink(outfilename);
  1268.         return;
  1269.     }
  1270.     write_stubs();
  1271. }
  1272.  
  1273. /*
  1274.  * Perform registrations for service output 
  1275.  */
  1276. static
  1277. do_registers(argc, argv)
  1278.     int argc;
  1279.     char *argv[];
  1280.  
  1281. {
  1282.     int i;
  1283.  
  1284.     for (i = 1; i < argc; i++) {
  1285.         if (streq(argv[i], "-s")) {
  1286.             write_register(argv[i + 1]);
  1287.             i++;
  1288.         }
  1289.     }
  1290. }
  1291.  
  1292. /*
  1293.  * Parse command line arguments 
  1294.  */
  1295. static
  1296. parseargs(argc, argv, cmd)
  1297.     int argc;
  1298.     char *argv[];
  1299.     struct commandline *cmd;
  1300.  
  1301. {
  1302.     int i;
  1303.     int j;
  1304.     char c;
  1305.     char flag[(1 << 8 * sizeof(char))];
  1306.     int nflags;
  1307.  
  1308.     cmdname = argv[0];
  1309.     cmd->infile = cmd->outfile = NULL;
  1310.     if (argc < 2) {
  1311.         return (0);
  1312.     }
  1313.     flag['c'] = 0;
  1314.     flag['h'] = 0;
  1315.     flag['s'] = 0;
  1316.     flag['o'] = 0;
  1317.     flag['l'] = 0;
  1318.     flag['m'] = 0;
  1319.     for (i = 1; i < argc; i++) {
  1320.         if (argv[i][0] != '-') {
  1321.             if (cmd->infile) {
  1322.                 return (0);
  1323.             }
  1324.             cmd->infile = argv[i];
  1325.         } else {
  1326.             for (j = 1; argv[i][j] != 0; j++) {
  1327.                 c = argv[i][j];
  1328.                 switch (c) {
  1329.                 case 'c':
  1330.                 case 'h':
  1331.                 case 'l':
  1332.                 case 'm':
  1333.                     if (flag[c]) {
  1334.                         return (0);
  1335.                     }
  1336.                     flag[c] = 1;
  1337.                     break;
  1338.                 case 'o':
  1339.                 case 's':
  1340.                     if (argv[i][j - 1] != '-' || 
  1341.                         argv[i][j + 1] != 0) {
  1342.                         return (0);
  1343.                     }
  1344.                     flag[c] = 1;
  1345.                     if (++i == argc) {
  1346.                         return (0);
  1347.                     }
  1348.                     if (c == 's') {
  1349.                         if (!streq(argv[i], "udp") &&
  1350.                             !streq(argv[i], "tcp")) {
  1351.                             return (0);
  1352.                         }
  1353.                     } else if (c == 'o') {
  1354.                         if (cmd->outfile) {
  1355.                             return (0);
  1356.                         }
  1357.                         cmd->outfile = argv[i];
  1358.                     }
  1359.                     goto nextarg;
  1360.  
  1361.                 default:
  1362.                     return (0);
  1363.                 }
  1364.             }
  1365.     nextarg:
  1366.             ;
  1367.         }
  1368.     }
  1369.     cmd->cflag = flag['c'];
  1370.     cmd->hflag = flag['h'];
  1371.     cmd->sflag = flag['s'];
  1372.     cmd->lflag = flag['l'];
  1373.     cmd->mflag = flag['m'];
  1374.     nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag;
  1375.     if (nflags == 0) {
  1376.         if (cmd->outfile != NULL || cmd->infile == NULL) {
  1377.             return (0);
  1378.         }
  1379.     } else if (nflags > 1) {
  1380.         return (0);
  1381.     }
  1382.     return (1);
  1383. }
  1384. Funky_Stuff
  1385. len=`wc -c < rpc_main.c`
  1386. if [ $len !=     9083 ] ; then
  1387.   echo error: rpc_main.c was $len bytes long, should have been     9083
  1388. fi
  1389. echo x - rpc_parse.c
  1390. cat > rpc_parse.c <<'Funky_Stuff'
  1391. /* @(#)rpc_parse.c    1.1 87/11/04 3.9 RPCSRC */
  1392. /*
  1393.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1394.  * unrestricted use provided that this legend is included on all tape
  1395.  * media and as a part of the software program in whole or part.  Users
  1396.  * may copy or modify Sun RPC without charge, but are not authorized
  1397.  * to license or distribute it to anyone else except as part of a product or
  1398.  * program developed by the user.
  1399.  * 
  1400.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1401.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1402.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1403.  * 
  1404.  * Sun RPC is provided with no support and without any obligation on the
  1405.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1406.  * modification or enhancement.
  1407.  * 
  1408.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1409.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1410.  * OR ANY PART THEREOF.
  1411.  * 
  1412.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1413.  * or profits or other special, indirect and consequential damages, even if
  1414.  * Sun has been advised of the possibility of such damages.
  1415.  * 
  1416.  * Sun Microsystems, Inc.
  1417.  * 2550 Garcia Avenue
  1418.  * Mountain View, California  94043
  1419.  */
  1420. #ifndef lint
  1421. static char sccsid[] = "@(#)rpc_parse.c 1.4 87/04/28 (C) 1987 SMI";
  1422. #endif
  1423.  
  1424. /*
  1425.  * rpc_parse.c, Parser for the RPC protocol compiler 
  1426.  * Copyright (C) 1987 Sun Microsystems, Inc.
  1427.  */
  1428. #include <stdio.h>
  1429. #include "rpc_util.h"
  1430. #include "rpc_scan.h"
  1431. #include "rpc_parse.h"
  1432.  
  1433. /*
  1434.  * return the next definition you see
  1435.  */
  1436. definition *
  1437. get_definition()
  1438. {
  1439.     definition *defp;
  1440.     token tok;
  1441.  
  1442.     defp = ALLOC(definition);
  1443.     get_token(&tok);
  1444.     switch (tok.kind) {
  1445.     case TOK_STRUCT:
  1446.         def_struct(defp);
  1447.         break;
  1448.     case TOK_UNION:
  1449.         def_union(defp);
  1450.         break;
  1451.     case TOK_TYPEDEF:
  1452.         def_typedef(defp);
  1453.         break;
  1454.     case TOK_ENUM:
  1455.         def_enum(defp);
  1456.         break;
  1457.     case TOK_PROGRAM:
  1458.         def_program(defp);
  1459.         break;
  1460.     case TOK_CONST:
  1461.         def_const(defp);
  1462.         break;
  1463.     case TOK_EOF:
  1464.         return (NULL);
  1465.         break;
  1466.     default:
  1467.         error("definition keyword expected");
  1468.     }
  1469.     scan(TOK_SEMICOLON, &tok);
  1470.     isdefined(defp);
  1471.     return (defp);
  1472. }
  1473.  
  1474. static
  1475. isdefined(defp)
  1476.     definition *defp;
  1477. {
  1478.     STOREVAL(&defined, defp);
  1479. }
  1480.  
  1481.  
  1482. static
  1483. def_struct(defp)
  1484.     definition *defp;
  1485. {
  1486.     token tok;
  1487.     declaration dec;
  1488.     decl_list *decls;
  1489.     decl_list **tailp;
  1490.  
  1491.     defp->def_kind = DEF_STRUCT;
  1492.  
  1493.     scan(TOK_IDENT, &tok);
  1494.     defp->def_name = tok.str;
  1495.     scan(TOK_LBRACE, &tok);
  1496.     tailp = &defp->def.st.decls;
  1497.     do {
  1498.         get_declaration(&dec, DEF_STRUCT);
  1499.         decls = ALLOC(decl_list);
  1500.         decls->decl = dec;
  1501.         *tailp = decls;
  1502.         tailp = &decls->next;
  1503.         scan(TOK_SEMICOLON, &tok);
  1504.         peek(&tok);
  1505.     } while (tok.kind != TOK_RBRACE);
  1506.     get_token(&tok);
  1507.     *tailp = NULL;
  1508. }
  1509.  
  1510. static
  1511. def_program(defp)
  1512.     definition *defp;
  1513. {
  1514.     token tok;
  1515.     version_list *vlist;
  1516.     version_list **vtailp;
  1517.     proc_list *plist;
  1518.     proc_list **ptailp;
  1519.  
  1520.     defp->def_kind = DEF_PROGRAM;
  1521.     scan(TOK_IDENT, &tok);
  1522.     defp->def_name = tok.str;
  1523.     scan(TOK_LBRACE, &tok);
  1524.     vtailp = &defp->def.pr.versions;
  1525.     scan(TOK_VERSION, &tok);
  1526.     do {
  1527.         scan(TOK_IDENT, &tok);
  1528.         vlist = ALLOC(version_list);
  1529.         vlist->vers_name = tok.str;
  1530.         scan(TOK_LBRACE, &tok);
  1531.         ptailp = &vlist->procs;
  1532.         do {
  1533.             plist = ALLOC(proc_list);
  1534.             get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
  1535.             if (streq(plist->res_type, "opaque")) {
  1536.                 error("illegal result type");
  1537.             }
  1538.             scan(TOK_IDENT, &tok);
  1539.             plist->proc_name = tok.str;
  1540.             scan(TOK_LPAREN, &tok);
  1541.             get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
  1542.             if (streq(plist->arg_type, "opaque")) {
  1543.                 error("illegal argument type");
  1544.             }
  1545.             scan(TOK_RPAREN, &tok);
  1546.             scan(TOK_EQUAL, &tok);
  1547.             scan_num(&tok);
  1548.             scan(TOK_SEMICOLON, &tok);
  1549.             plist->proc_num = tok.str;
  1550.             *ptailp = plist;
  1551.             ptailp = &plist->next;
  1552.             peek(&tok);
  1553.         } while (tok.kind != TOK_RBRACE);
  1554.         *vtailp = vlist;
  1555.         vtailp = &vlist->next;
  1556.         scan(TOK_RBRACE, &tok);
  1557.         scan(TOK_EQUAL, &tok);
  1558.         scan_num(&tok);
  1559.         vlist->vers_num = tok.str;
  1560.         scan(TOK_SEMICOLON, &tok);
  1561.         scan2(TOK_VERSION, TOK_RBRACE, &tok);
  1562.     } while (tok.kind == TOK_VERSION);
  1563.     scan(TOK_EQUAL, &tok);
  1564.     scan_num(&tok);
  1565.     defp->def.pr.prog_num = tok.str;
  1566.     *vtailp = NULL;
  1567. }
  1568.  
  1569. static
  1570. def_enum(defp)
  1571.     definition *defp;
  1572. {
  1573.     token tok;
  1574.     enumval_list *elist;
  1575.     enumval_list **tailp;
  1576.  
  1577.     defp->def_kind = DEF_ENUM;
  1578.     scan(TOK_IDENT, &tok);
  1579.     defp->def_name = tok.str;
  1580.     scan(TOK_LBRACE, &tok);
  1581.     tailp = &defp->def.en.vals;
  1582.     do {
  1583.         scan(TOK_IDENT, &tok);
  1584.         elist = ALLOC(enumval_list);
  1585.         elist->name = tok.str;
  1586.         elist->assignment = NULL;
  1587.         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
  1588.         if (tok.kind == TOK_EQUAL) {
  1589.             scan_num(&tok);
  1590.             elist->assignment = tok.str;
  1591.             scan2(TOK_COMMA, TOK_RBRACE, &tok);
  1592.         }
  1593.         *tailp = elist;
  1594.         tailp = &elist->next;
  1595.     } while (tok.kind != TOK_RBRACE);
  1596.     *tailp = NULL;
  1597. }
  1598.  
  1599. static
  1600. def_const(defp)
  1601.     definition *defp;
  1602. {
  1603.     token tok;
  1604.  
  1605.     defp->def_kind = DEF_CONST;
  1606.     scan(TOK_IDENT, &tok);
  1607.     defp->def_name = tok.str;
  1608.     scan(TOK_EQUAL, &tok);
  1609.     scan2(TOK_IDENT, TOK_STRCONST, &tok);
  1610.     defp->def.co = tok.str;
  1611. }
  1612.  
  1613. static
  1614. def_union(defp)
  1615.     definition *defp;
  1616. {
  1617.     token tok;
  1618.     declaration dec;
  1619.     case_list *cases;
  1620.     case_list **tailp;
  1621.  
  1622.     defp->def_kind = DEF_UNION;
  1623.     scan(TOK_IDENT, &tok);
  1624.     defp->def_name = tok.str;
  1625.     scan(TOK_SWITCH, &tok);
  1626.     scan(TOK_LPAREN, &tok);
  1627.     get_declaration(&dec, DEF_UNION);
  1628.     defp->def.un.enum_decl = dec;
  1629.     tailp = &defp->def.un.cases;
  1630.     scan(TOK_RPAREN, &tok);
  1631.     scan(TOK_LBRACE, &tok);
  1632.     scan(TOK_CASE, &tok);
  1633.     while (tok.kind == TOK_CASE) {
  1634.         scan(TOK_IDENT, &tok);
  1635.         cases = ALLOC(case_list);
  1636.         cases->case_name = tok.str;
  1637.         scan(TOK_COLON, &tok);
  1638.         get_declaration(&dec, DEF_UNION);
  1639.         cases->case_decl = dec;
  1640.         *tailp = cases;
  1641.         tailp = &cases->next;
  1642.         scan(TOK_SEMICOLON, &tok);
  1643.         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
  1644.     }
  1645.     *tailp = NULL;
  1646.     if (tok.kind == TOK_DEFAULT) {
  1647.         scan(TOK_COLON, &tok);
  1648.         get_declaration(&dec, DEF_UNION);
  1649.         defp->def.un.default_decl = ALLOC(declaration);
  1650.         *defp->def.un.default_decl = dec;
  1651.         scan(TOK_SEMICOLON, &tok);
  1652.         scan(TOK_RBRACE, &tok);
  1653.     } else {
  1654.         defp->def.un.default_decl = NULL;
  1655.     }
  1656. }
  1657.  
  1658.  
  1659. static
  1660. def_typedef(defp)
  1661.     definition *defp;
  1662. {
  1663.     declaration dec;
  1664.  
  1665.     defp->def_kind = DEF_TYPEDEF;
  1666.     get_declaration(&dec, DEF_TYPEDEF);
  1667.     defp->def_name = dec.name;
  1668.     defp->def.ty.old_prefix = dec.prefix;
  1669.     defp->def.ty.old_type = dec.type;
  1670.     defp->def.ty.rel = dec.rel;
  1671.     defp->def.ty.array_max = dec.array_max;
  1672. }
  1673.  
  1674.  
  1675. static
  1676. get_declaration(dec, dkind)
  1677.     declaration *dec;
  1678.     defkind dkind;
  1679. {
  1680.     token tok;
  1681.  
  1682.     get_type(&dec->prefix, &dec->type, dkind);
  1683.     dec->rel = REL_ALIAS;
  1684.     if (streq(dec->type, "void")) {
  1685.         return;
  1686.     }
  1687.     scan2(TOK_STAR, TOK_IDENT, &tok);
  1688.     if (tok.kind == TOK_STAR) {
  1689.         dec->rel = REL_POINTER;
  1690.         scan(TOK_IDENT, &tok);
  1691.     }
  1692.     dec->name = tok.str;
  1693.     if (peekscan(TOK_LBRACKET, &tok)) {
  1694.         if (dec->rel == REL_POINTER) {
  1695.             error("no array-of-pointer declarations -- use typedef");
  1696.         }
  1697.         dec->rel = REL_VECTOR;
  1698.         scan_num(&tok);
  1699.         dec->array_max = tok.str;
  1700.         scan(TOK_RBRACKET, &tok);
  1701.     } else if (peekscan(TOK_LANGLE, &tok)) {
  1702.         if (dec->rel == REL_POINTER) {
  1703.             error("no array-of-pointer declarations -- use typedef");
  1704.         }
  1705.         dec->rel = REL_ARRAY;
  1706.         if (peekscan(TOK_RANGLE, &tok)) {
  1707.             dec->array_max = "~0";    /* unspecified size, use max */
  1708.         } else {
  1709.             scan_num(&tok);
  1710.             dec->array_max = tok.str;
  1711.             scan(TOK_RANGLE, &tok);
  1712.         }
  1713.     }
  1714.     if (streq(dec->type, "opaque")) {
  1715.         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
  1716.             error("array declaration expected");
  1717.         }
  1718.     } else if (streq(dec->type, "string")) {
  1719.         if (dec->rel != REL_ARRAY) {
  1720.             error("variable-length array declaration expected");
  1721.         }
  1722.     }
  1723. }
  1724.  
  1725.  
  1726. static
  1727. get_type(prefixp, typep, dkind)
  1728.     char **prefixp;
  1729.     char **typep;
  1730.     defkind dkind;
  1731. {
  1732.     token tok;
  1733.  
  1734.     *prefixp = NULL;
  1735.     get_token(&tok);
  1736.     switch (tok.kind) {
  1737.     case TOK_IDENT:
  1738.         *typep = tok.str;
  1739.         break;
  1740.     case TOK_STRUCT:
  1741.     case TOK_ENUM:
  1742.     case TOK_UNION:
  1743.         *prefixp = tok.str;
  1744.         scan(TOK_IDENT, &tok);
  1745.         *typep = tok.str;
  1746.         break;
  1747.     case TOK_UNSIGNED:
  1748.         unsigned_dec(typep);
  1749.         break;
  1750.     case TOK_SHORT:
  1751.         *typep = "short";
  1752.         (void) peekscan(TOK_INT, &tok);
  1753.         break;
  1754.     case TOK_LONG:
  1755.         *typep = "long";
  1756.         (void) peekscan(TOK_INT, &tok);
  1757.         break;
  1758.     case TOK_VOID:
  1759.         if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
  1760.             error("voids allowed only inside union and program definitions");
  1761.         }
  1762.         *typep = tok.str;
  1763.         break;
  1764.     case TOK_STRING:
  1765.     case TOK_OPAQUE:
  1766.     case TOK_CHAR:
  1767.     case TOK_INT:
  1768.     case TOK_FLOAT:
  1769.     case TOK_DOUBLE:
  1770.     case TOK_BOOL:
  1771.         *typep = tok.str;
  1772.         break;
  1773.     default:
  1774.         error("expected type specifier");
  1775.     }
  1776. }
  1777.  
  1778.  
  1779. static
  1780. unsigned_dec(typep)
  1781.     char **typep;
  1782. {
  1783.     token tok;
  1784.  
  1785.     peek(&tok);
  1786.     switch (tok.kind) {
  1787.     case TOK_CHAR:
  1788.         get_token(&tok);
  1789.         *typep = "u_char";
  1790.         break;
  1791.     case TOK_SHORT:
  1792.         get_token(&tok);
  1793.         *typep = "u_short";
  1794.         (void) peekscan(TOK_INT, &tok);
  1795.         break;
  1796.     case TOK_LONG:
  1797.         get_token(&tok);
  1798.         *typep = "u_long";
  1799.         (void) peekscan(TOK_INT, &tok);
  1800.         break;
  1801.     case TOK_INT:
  1802.         get_token(&tok);
  1803.         *typep = "u_int";
  1804.         break;
  1805.     default:
  1806.         *typep = "u_int";
  1807.         break;
  1808.     }
  1809. }
  1810. Funky_Stuff
  1811. len=`wc -c < rpc_parse.c`
  1812. if [ $len !=     8998 ] ; then
  1813.   echo error: rpc_parse.c was $len bytes long, should have been     8998
  1814. fi
  1815. echo x - rpc_parse.h
  1816. cat > rpc_parse.h <<'Funky_Stuff'
  1817. /*
  1818.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1819.  * unrestricted use provided that this legend is included on all tape
  1820.  * media and as a part of the software program in whole or part.  Users
  1821.  * may copy or modify Sun RPC without charge, but are not authorized
  1822.  * to license or distribute it to anyone else except as part of a product or
  1823.  * program developed by the user.
  1824.  * 
  1825.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1826.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1827.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1828.  * 
  1829.  * Sun RPC is provided with no support and without any obligation on the
  1830.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1831.  * modification or enhancement.
  1832.  * 
  1833.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1834.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1835.  * OR ANY PART THEREOF.
  1836.  * 
  1837.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1838.  * or profits or other special, indirect and consequential damages, even if
  1839.  * Sun has been advised of the possibility of such damages.
  1840.  * 
  1841.  * Sun Microsystems, Inc.
  1842.  * 2550 Garcia Avenue
  1843.  * Mountain View, California  94043
  1844.  */
  1845. /* @(#)rpc_parse.h 1.3 87/03/09 (C) 1987 SMI */
  1846.  
  1847. /*
  1848.  * rpc_parse.h, Definitions for the RPCL parser 
  1849.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  1850.  */
  1851.  
  1852. enum defkind {
  1853.     DEF_CONST,
  1854.     DEF_STRUCT,
  1855.     DEF_UNION,
  1856.     DEF_ENUM,
  1857.     DEF_TYPEDEF,
  1858.     DEF_PROGRAM
  1859. };
  1860. typedef enum defkind defkind;
  1861.  
  1862. typedef char *const_def;
  1863.  
  1864. enum relation {
  1865.     REL_VECTOR,    /* fixed length array */
  1866.     REL_ARRAY,    /* variable length array */
  1867.     REL_POINTER,    /* pointer */
  1868.     REL_ALIAS,    /* simple */
  1869. };
  1870. typedef enum relation relation;
  1871.  
  1872. struct typedef_def {
  1873.     char *old_prefix;
  1874.     char *old_type;
  1875.     relation rel;
  1876.     char *array_max;
  1877. };
  1878. typedef struct typedef_def typedef_def;
  1879.  
  1880.  
  1881. struct enumval_list {
  1882.     char *name;
  1883.     char *assignment;
  1884.     struct enumval_list *next;
  1885. };
  1886. typedef struct enumval_list enumval_list;
  1887.  
  1888. struct enum_def {
  1889.     enumval_list *vals;
  1890. };
  1891. typedef struct enum_def enum_def;
  1892.  
  1893.  
  1894. struct declaration {
  1895.     char *prefix;
  1896.     char *type;
  1897.     char *name;
  1898.     relation rel;
  1899.     char *array_max;
  1900. };
  1901. typedef struct declaration declaration;
  1902.  
  1903.  
  1904. struct decl_list {
  1905.     declaration decl;
  1906.     struct decl_list *next;
  1907. };
  1908. typedef struct decl_list decl_list;
  1909.  
  1910. struct struct_def {
  1911.     decl_list *decls;
  1912. };
  1913. typedef struct struct_def struct_def;
  1914.  
  1915.  
  1916. struct case_list {
  1917.     char *case_name;
  1918.     declaration case_decl;
  1919.     struct case_list *next;
  1920. };
  1921. typedef struct case_list case_list;
  1922.  
  1923. struct union_def {
  1924.     declaration enum_decl;
  1925.     case_list *cases;
  1926.     declaration *default_decl;
  1927. };
  1928. typedef struct union_def union_def;
  1929.  
  1930.  
  1931.  
  1932. struct proc_list {
  1933.     char *proc_name;
  1934.     char *proc_num;
  1935.     char *arg_type;
  1936.     char *arg_prefix;
  1937.     char *res_type;
  1938.     char *res_prefix;
  1939.     struct proc_list *next;
  1940. };
  1941. typedef struct proc_list proc_list;
  1942.  
  1943.  
  1944. struct version_list {
  1945.     char *vers_name;
  1946.     char *vers_num;
  1947.     proc_list *procs;
  1948.     struct version_list *next;
  1949. };
  1950. typedef struct version_list version_list;
  1951.  
  1952. struct program_def {
  1953.     char *prog_num;
  1954.     version_list *versions;
  1955. };
  1956. typedef struct program_def program_def;
  1957.  
  1958. struct definition {
  1959.     char *def_name;
  1960.     defkind def_kind;
  1961.     union {
  1962.         const_def co;
  1963.         struct_def st;
  1964.         union_def un;
  1965.         enum_def en;
  1966.         typedef_def ty;
  1967.         program_def pr;
  1968.     } def;
  1969. };
  1970. typedef struct definition definition;
  1971.  
  1972. /* @(#)rpc_parse.h    1.2 87/11/19 3.9 RPCSRC */
  1973. definition *get_definition();
  1974. Funky_Stuff
  1975. len=`wc -c < rpc_parse.h`
  1976. if [ $len !=     3419 ] ; then
  1977.   echo error: rpc_parse.h was $len bytes long, should have been     3419
  1978. fi
  1979. echo x - rpc_scan.c
  1980. cat > rpc_scan.c <<'Funky_Stuff'
  1981. /* @(#)rpc_scan.c    1.1 87/11/04 3.9 RPCSRC */
  1982. /*
  1983.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1984.  * unrestricted use provided that this legend is included on all tape
  1985.  * media and as a part of the software program in whole or part.  Users
  1986.  * may copy or modify Sun RPC without charge, but are not authorized
  1987.  * to license or distribute it to anyone else except as part of a product or
  1988.  * program developed by the user.
  1989.  * 
  1990.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1991.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1992.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1993.  * 
  1994.  * Sun RPC is provided with no support and without any obligation on the
  1995.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1996.  * modification or enhancement.
  1997.  * 
  1998.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1999.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  2000.  * OR ANY PART THEREOF.
  2001.  * 
  2002.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  2003.  * or profits or other special, indirect and consequential damages, even if
  2004.  * Sun has been advised of the possibility of such damages.
  2005.  * 
  2006.  * Sun Microsystems, Inc.
  2007.  * 2550 Garcia Avenue
  2008.  * Mountain View, California  94043
  2009.  */
  2010. #ifndef lint
  2011. static char sccsid[] = "@(#)rpc_scan.c 1.6 87/06/24 (C) 1987 SMI";
  2012. #endif
  2013.  
  2014. /*
  2015.  * rpc_scan.c, Scanner for the RPC protocol compiler 
  2016.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  2017.  */
  2018. #include <stdio.h>
  2019. #include <ctype.h>
  2020. #include <strings.h>
  2021. #include "rpc_scan.h"
  2022. #include "rpc_util.h"
  2023.  
  2024. #define startcomment(where) (where[0] == '/' && where[1] == '*')
  2025. #define endcomment(where) (where[-1] == '*' && where[0] == '/')
  2026.  
  2027. static int pushed = 0;    /* is a token pushed */
  2028. static token lasttok;    /* last token, if pushed */
  2029.  
  2030. /*
  2031.  * scan expecting 1 given token 
  2032.  */
  2033. void
  2034. scan(expect, tokp)
  2035.     tok_kind expect;
  2036.     token *tokp;
  2037. {
  2038.     get_token(tokp);
  2039.     if (tokp->kind != expect) {
  2040.         expected1(expect);
  2041.     }
  2042. }
  2043.  
  2044. /*
  2045.  * scan expecting 2 given tokens 
  2046.  */
  2047. void
  2048. scan2(expect1, expect2, tokp)
  2049.     tok_kind expect1;
  2050.     tok_kind expect2;
  2051.     token *tokp;
  2052. {
  2053.     get_token(tokp);
  2054.     if (tokp->kind != expect1 && tokp->kind != expect2) {
  2055.         expected2(expect1, expect2);
  2056.     }
  2057. }
  2058.  
  2059. /*
  2060.  * scan expecting 3 given token 
  2061.  */
  2062. void
  2063. scan3(expect1, expect2, expect3, tokp)
  2064.     tok_kind expect1;
  2065.     tok_kind expect2;
  2066.     tok_kind expect3;
  2067.     token *tokp;
  2068. {
  2069.     get_token(tokp);
  2070.     if (tokp->kind != expect1 && tokp->kind != expect2
  2071.         && tokp->kind != expect3) {
  2072.         expected3(expect1, expect2, expect3);
  2073.     }
  2074. }
  2075.  
  2076.  
  2077. /*
  2078.  * scan expecting a constant, possibly symbolic 
  2079.  */
  2080. void
  2081. scan_num(tokp)
  2082.     token *tokp;
  2083. {
  2084.     get_token(tokp);
  2085.     switch (tokp->kind) {
  2086.     case TOK_IDENT:
  2087.         break;
  2088.     default:
  2089.         error("constant or identifier expected");
  2090.     }
  2091. }
  2092.  
  2093.  
  2094. /*
  2095.  * Peek at the next token 
  2096.  */
  2097. void
  2098. peek(tokp)
  2099.     token *tokp;
  2100. {
  2101.     get_token(tokp);
  2102.     unget_token(tokp);
  2103. }
  2104.  
  2105.  
  2106. /*
  2107.  * Peek at the next token and scan it if it matches what you expect 
  2108.  */
  2109. int
  2110. peekscan(expect, tokp)
  2111.     tok_kind expect;
  2112.     token *tokp;
  2113. {
  2114.     peek(tokp);
  2115.     if (tokp->kind == expect) {
  2116.         get_token(tokp);
  2117.         return (1);
  2118.     }
  2119.     return (0);
  2120. }
  2121.  
  2122.  
  2123.  
  2124. /*
  2125.  * Get the next token, printing out any directive that are encountered. 
  2126.  */
  2127. void
  2128. get_token(tokp)
  2129.     token *tokp;
  2130. {
  2131.     int commenting;
  2132.  
  2133.     if (pushed) {
  2134.         pushed = 0;
  2135.         *tokp = lasttok;
  2136.         return;
  2137.     }
  2138.     commenting = 0;
  2139.     for (;;) {
  2140.         if (*where == 0) {
  2141.             for (;;) {
  2142.                 if (!fgets(curline, MAXLINESIZE, fin)) {
  2143.                     tokp->kind = TOK_EOF;
  2144.                     *where = 0;
  2145.                     return;
  2146.                 }
  2147.                 linenum++;
  2148.                 if (commenting) {
  2149.                     break;
  2150.                 } else if (cppline(curline)) {
  2151.                     docppline(curline, &linenum, 
  2152.                           &infilename);
  2153.                 } else if (directive(curline)) {
  2154.                     printdirective(curline);
  2155.                 } else {
  2156.                     break;
  2157.                 }
  2158.             }
  2159.             where = curline;
  2160.         } else if (isspace(*where)) {
  2161.             while (isspace(*where)) {
  2162.                 where++;    /* eat */
  2163.             }
  2164.         } else if (commenting) {
  2165.             where++;
  2166.             if (endcomment(where)) {
  2167.                 where++;
  2168.                 commenting--;
  2169.             }
  2170.         } else if (startcomment(where)) {
  2171.             where += 2;
  2172.             commenting++;
  2173.         } else {
  2174.             break;
  2175.         }
  2176.     }
  2177.  
  2178.     /*
  2179.      * 'where' is not whitespace, comment or directive Must be a token! 
  2180.      */
  2181.     switch (*where) {
  2182.     case ':':
  2183.         tokp->kind = TOK_COLON;
  2184.         where++;
  2185.         break;
  2186.     case ';':
  2187.         tokp->kind = TOK_SEMICOLON;
  2188.         where++;
  2189.         break;
  2190.     case ',':
  2191.         tokp->kind = TOK_COMMA;
  2192.         where++;
  2193.         break;
  2194.     case '=':
  2195.         tokp->kind = TOK_EQUAL;
  2196.         where++;
  2197.         break;
  2198.     case '*':
  2199.         tokp->kind = TOK_STAR;
  2200.         where++;
  2201.         break;
  2202.     case '[':
  2203.         tokp->kind = TOK_LBRACKET;
  2204.         where++;
  2205.         break;
  2206.     case ']':
  2207.         tokp->kind = TOK_RBRACKET;
  2208.         where++;
  2209.         break;
  2210.     case '{':
  2211.         tokp->kind = TOK_LBRACE;
  2212.         where++;
  2213.         break;
  2214.     case '}':
  2215.         tokp->kind = TOK_RBRACE;
  2216.         where++;
  2217.         break;
  2218.     case '(':
  2219.         tokp->kind = TOK_LPAREN;
  2220.         where++;
  2221.         break;
  2222.     case ')':
  2223.         tokp->kind = TOK_RPAREN;
  2224.         where++;
  2225.         break;
  2226.     case '<':
  2227.         tokp->kind = TOK_LANGLE;
  2228.         where++;
  2229.         break;
  2230.     case '>':
  2231.         tokp->kind = TOK_RANGLE;
  2232.         where++;
  2233.         break;
  2234.  
  2235.     case '"':
  2236.         tokp->kind = TOK_STRCONST;
  2237.         findstrconst(&where, &tokp->str);
  2238.         break;
  2239.  
  2240.     case '-':
  2241.     case '0':
  2242.     case '1':
  2243.     case '2':
  2244.     case '3':
  2245.     case '4':
  2246.     case '5':
  2247.     case '6':
  2248.     case '7':
  2249.     case '8':
  2250.     case '9':
  2251.         tokp->kind = TOK_IDENT;
  2252.         findconst(&where, &tokp->str);
  2253.         break;
  2254.  
  2255.  
  2256.     default:
  2257.         if (!(isalpha(*where) || *where == '_')) {
  2258.             char buf[100];
  2259.             char *p;
  2260.  
  2261.             s_print(buf, "illegal character in file: ");
  2262.             p = buf + strlen(buf);
  2263.             if (isprint(*where)) {
  2264.                 s_print(p, "%c", *where);
  2265.             } else {
  2266.                 s_print(p, "%d", *where);
  2267.             }
  2268.             error(buf);
  2269.         }
  2270.         findkind(&where, tokp);
  2271.         break;
  2272.     }
  2273. }
  2274.  
  2275.  
  2276.  
  2277. static
  2278. unget_token(tokp)
  2279.     token *tokp;
  2280. {
  2281.     lasttok = *tokp;
  2282.     pushed = 1;
  2283. }
  2284.  
  2285.  
  2286. static
  2287. findstrconst(str, val)
  2288.     char **str;
  2289.     char **val;
  2290. {
  2291.     char *p;
  2292.     int size;
  2293.  
  2294.     p = *str;
  2295.     do {
  2296.         *p++;
  2297.     } while (*p && *p != '"');
  2298.     if (*p == 0) {
  2299.         error("unterminated string constant");
  2300.     }
  2301.     p++;
  2302.     size = p - *str;
  2303.     *val = alloc(size + 1);
  2304.     (void) strncpy(*val, *str, size);
  2305.     (*val)[size] = 0;
  2306.     *str = p;
  2307. }
  2308.  
  2309. static
  2310. findconst(str, val)
  2311.     char **str;
  2312.     char **val;
  2313. {
  2314.     char *p;
  2315.     int size;
  2316.  
  2317.     p = *str;
  2318.     if (*p == '0' && *(p + 1) == 'x') {
  2319.         p++;
  2320.         do {
  2321.             p++;
  2322.         } while (isxdigit(*p));
  2323.     } else {
  2324.         do {
  2325.             p++;
  2326.         } while (isdigit(*p));
  2327.     }
  2328.     size = p - *str;
  2329.     *val = alloc(size + 1);
  2330.     (void) strncpy(*val, *str, size);
  2331.     (*val)[size] = 0;
  2332.     *str = p;
  2333. }
  2334.  
  2335.  
  2336.  
  2337. static token symbols[] = {
  2338.               {TOK_CONST, "const"},
  2339.               {TOK_UNION, "union"},
  2340.               {TOK_SWITCH, "switch"},
  2341.               {TOK_CASE, "case"},
  2342.               {TOK_DEFAULT, "default"},
  2343.               {TOK_STRUCT, "struct"},
  2344.               {TOK_TYPEDEF, "typedef"},
  2345.               {TOK_ENUM, "enum"},
  2346.               {TOK_OPAQUE, "opaque"},
  2347.               {TOK_BOOL, "bool"},
  2348.               {TOK_VOID, "void"},
  2349.               {TOK_CHAR, "char"},
  2350.               {TOK_INT, "int"},
  2351.               {TOK_UNSIGNED, "unsigned"},
  2352.               {TOK_SHORT, "short"},
  2353.               {TOK_LONG, "long"},
  2354.               {TOK_FLOAT, "float"},
  2355.               {TOK_DOUBLE, "double"},
  2356.               {TOK_STRING, "string"},
  2357.               {TOK_PROGRAM, "program"},
  2358.               {TOK_VERSION, "version"},
  2359.               {TOK_EOF, "??????"},
  2360. };
  2361.  
  2362.  
  2363. static
  2364. findkind(mark, tokp)
  2365.     char **mark;
  2366.     token *tokp;
  2367. {
  2368.  
  2369.     int len;
  2370.     token *s;
  2371.     char *str;
  2372.  
  2373.     str = *mark;
  2374.     for (s = symbols; s->kind != TOK_EOF; s++) {
  2375.         len = strlen(s->str);
  2376.         if (strncmp(str, s->str, len) == 0) {
  2377.             if (!isalnum(str[len]) && str[len] != '_') {
  2378.                 tokp->kind = s->kind;
  2379.                 tokp->str = s->str;
  2380.                 *mark = str + len;
  2381.                 return;
  2382.             }
  2383.         }
  2384.     }
  2385.     tokp->kind = TOK_IDENT;
  2386.     for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
  2387.     tokp->str = alloc(len + 1);
  2388.     (void) strncpy(tokp->str, str, len);
  2389.     tokp->str[len] = 0;
  2390.     *mark = str + len;
  2391. }
  2392.  
  2393. static
  2394. cppline(line)
  2395.     char *line;
  2396. {
  2397.     return (line == curline && *line == '#');
  2398. }
  2399.  
  2400. static
  2401. directive(line)
  2402.     char *line;
  2403. {
  2404.     return (line == curline && *line == '%');
  2405. }
  2406.  
  2407. static
  2408. printdirective(line)
  2409.     char *line;
  2410. {
  2411.     f_print(fout, "%s", line + 1);
  2412. }
  2413.  
  2414. static
  2415. docppline(line, lineno, fname)
  2416.     char *line;
  2417.     int *lineno;
  2418.     char **fname;
  2419. {
  2420.     char *file;
  2421.     int num;
  2422.     char *p;
  2423.  
  2424.     line++;
  2425.     while (isspace(*line)) {
  2426.         line++;
  2427.     }
  2428.     num = atoi(line);
  2429.     while (isdigit(*line)) {
  2430.         line++;
  2431.     }
  2432.     while (isspace(*line)) {
  2433.         line++;
  2434.     }
  2435.     if (*line != '"') {
  2436.         error("preprocessor error");
  2437.     }
  2438.     line++;
  2439.     p = file = alloc(strlen(line) + 1);
  2440.     while (*line && *line != '"') {
  2441.         *p++ = *line++;
  2442.     }
  2443.     if (*line == 0) {
  2444.         error("preprocessor error");
  2445.     }
  2446.     *p = 0;
  2447.     if (*file == 0) {
  2448.         *fname = NULL;
  2449.     } else {
  2450.         *fname = file;
  2451.     }
  2452.     *lineno = num - 1;
  2453. }
  2454. Funky_Stuff
  2455. len=`wc -c < rpc_scan.c`
  2456. if [ $len !=     8235 ] ; then
  2457.   echo error: rpc_scan.c was $len bytes long, should have been     8235
  2458. fi
  2459. echo x - rpc_scan.h
  2460. cat > rpc_scan.h <<'Funky_Stuff'
  2461. /* @(#)rpc_scan.h    1.1 87/11/04 3.9 RPCSRC */
  2462. /*
  2463.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  2464.  * unrestricted use provided that this legend is included on all tape
  2465.  * media and as a part of the software program in whole or part.  Users
  2466.  * may copy or modify Sun RPC without charge, but are not authorized
  2467.  * to license or distribute it to anyone else except as part of a product or
  2468.  * program developed by the user.
  2469.  * 
  2470.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  2471.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  2472.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  2473.  * 
  2474.  * Sun RPC is provided with no support and without any obligation on the
  2475.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  2476.  * modification or enhancement.
  2477.  * 
  2478.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  2479.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  2480.  * OR ANY PART THEREOF.
  2481.  * 
  2482.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  2483.  * or profits or other special, indirect and consequential damages, even if
  2484.  * Sun has been advised of the possibility of such damages.
  2485.  * 
  2486.  * Sun Microsystems, Inc.
  2487.  * 2550 Garcia Avenue
  2488.  * Mountain View, California  94043
  2489.  */
  2490. /* @(#)rpc_scan.h 1.3 87/03/09 (C) 1987 SMI */
  2491.  
  2492. /*
  2493.  * rpc_scan.h, Definitions for the RPCL scanner 
  2494.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  2495.  */
  2496.  
  2497. /*
  2498.  * kinds of tokens 
  2499.  */
  2500. enum tok_kind {
  2501.     TOK_IDENT,
  2502.     TOK_STRCONST,
  2503.     TOK_LPAREN,
  2504.     TOK_RPAREN,
  2505.     TOK_LBRACE,
  2506.     TOK_RBRACE,
  2507.     TOK_LBRACKET,
  2508.     TOK_RBRACKET,
  2509.     TOK_LANGLE,
  2510.     TOK_RANGLE,
  2511.     TOK_STAR,
  2512.     TOK_COMMA,
  2513.     TOK_EQUAL,
  2514.     TOK_COLON,
  2515.     TOK_SEMICOLON,
  2516.     TOK_CONST,
  2517.     TOK_STRUCT,
  2518.     TOK_UNION,
  2519.     TOK_SWITCH,
  2520.     TOK_CASE,
  2521.     TOK_DEFAULT,
  2522.     TOK_ENUM,
  2523.     TOK_TYPEDEF,
  2524.     TOK_INT,
  2525.     TOK_SHORT,
  2526.     TOK_LONG,
  2527.     TOK_UNSIGNED,
  2528.     TOK_FLOAT,
  2529.     TOK_DOUBLE,
  2530.     TOK_OPAQUE,
  2531.     TOK_CHAR,
  2532.     TOK_STRING,
  2533.     TOK_BOOL,
  2534.     TOK_VOID,
  2535.     TOK_PROGRAM,
  2536.     TOK_VERSION,
  2537.     TOK_EOF
  2538. };
  2539. typedef enum tok_kind tok_kind;
  2540.  
  2541. /*
  2542.  * a token 
  2543.  */
  2544. struct token {
  2545.     tok_kind kind;
  2546.     char *str;
  2547. };
  2548. typedef struct token token;
  2549.  
  2550.  
  2551. /*
  2552.  * routine interface 
  2553.  */
  2554. void scanprint();
  2555. void scan();
  2556. void scan2();
  2557. void scan3();
  2558. void scan_num();
  2559. void peek();
  2560. int peekscan();
  2561. void get_token();
  2562. Funky_Stuff
  2563. len=`wc -c < rpc_scan.h`
  2564. if [ $len !=     2259 ] ; then
  2565.   echo error: rpc_scan.h was $len bytes long, should have been     2259
  2566. fi
  2567. cd ..
  2568. echo more files to follow
  2569. exit
  2570.